package org.test4j.mock.stub;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * The static details about a method and the run-time details of its invocation.
 *
 * @author wudarui
 */
public class ProxyInvocation {
    public static final Object[] NO_PARAMETERS = null;

    private final Object target;
    private final Method method;
    private final Object[] args;

    public ProxyInvocation(Object invoked, Method method, Object... args) {
        this.target = invoked;
        this.method = method;
        this.args = (args == NO_PARAMETERS) ? new Object[0] : args.clone();
    }

    @Override
    public String toString() {
        return super.toString() + "[" + this.describe() + "]";
    }

    @Override
    public boolean equals(Object other) {
        return (other instanceof ProxyInvocation) && this.equals((ProxyInvocation) other);
    }

    public boolean equals(ProxyInvocation other) {
        return other != null && target == other.target && method.equals(other.method)
            && Arrays.equals(args, other.args);
    }

    @Override
    public int hashCode() {
        return target.hashCode() ^ method.hashCode() ^ Arrays.hashCode(args);
    }

    public String describe() {
        StringBuilder buff = new StringBuilder();
        buff.append(target);
        buff.append(".");
        buff.append(method.getName());
        buff.append(Impostor.describe(args));
        return buff.toString();
    }

    public Method getMethod() {
        return method;
    }

    public Object[] getParametersAsArray() {
        return args.clone();
    }
}